#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.8.1
 Author:         myName

 Script Function:
	Template AutoIt script.

#ce ----------------------------------------------------------------------------

Global $chest[9][2] = [[-2,0],[-1,0],[0,0],[1,0],[2,0],[0,-2],[0,-1],[0,1],[0,2]]
Global $block[9][2] = [[-1,-1],[-1,0],[-1,1],[0,-1],[0,0],[0,1],[1,-1],[1,0],[1,1]]
Global $swap_right[2] = [0,1]
Global $swap_bottom[2] = [1,0]
Global $g1[1][3] = [["apply_spell", "show_spell", $chest]]
Global $g2[1][3] = [["apply_spell", "show_spell", $block]]
Global $g3[2][3] = [ _
	["apply_swap", "show_swap", $swap_right], _
	["apply_swap", "show_swap", $swap_bottom] _
]

Global $move[3][3] = [ _
	["shift", $g3, True], _
	["cross", $g1, True], _
	["block", $g2, True] _
]

Func call_apply($func,ByRef $map, ByRef $award, ByRef $r, ByRef $c, ByRef $matrix, ByRef $log, $make_forecast = True)
	Switch $func
		Case "apply_spell"
			Return apply_spell($map, $award, $r, $c, $matrix, $log, $make_forecast)
		Case "apply_swap"
			Return apply_swap($map, $award, $r, $c, $matrix, $log, $make_forecast)
		Case Else
			MsgBox(0,"error","no func: " & $func
	EndSwitch
EndFunc


Func show_variant(ByRef $v)
	;[$m,$g,$r,$c,$award]
	Local $group = $move[$v[0]][1]
	Local $map = create_map()
	set_label("show: " & $group[$v[1]][1])
	Switch $group[$v[1]][1]
		Case "show_swap"
			show_swap($map, $v[2], $v[3], $group[$v[1]][2])
		Case "show_spell"
			show_spell($map, $v[2], $v[3], $group[$v[1]][2])
		Case Else
			MsgBox(0,"error","no func: " & $group[$v[1]][1]
	EndSwitch
	Return $map
EndFunc

Func apply_variant(ByRef $map,ByRef $v)
	Local $group = $move[$v[0]][1]
	set_label("apply: " & $group[$v[1]][1])
	Local $award = create_award()
	call_apply($group[$v[1]][0],$map,$award,$v[2], $v[3],$group[$v[1]][2],False,False)
EndFunc


Func apply_swap(ByRef $map, ByRef $award, $r, $c, ByRef $matrix, ByRef $log, $make_forecast = True)
	;If $log Then $log &= "apply_swap(" & $r & ", " & $c & ")" & @CRLF
	Local $nr = $r + $matrix[0]
	Local $nc = $c + $matrix[1]
	If $nr < $row_length And $nc < $col_length Then
		Local $v = $map[$r][$c]
		$map[$r][$c] = $map[$nr][$nc]
		$map[$nr][$nc] = $v
		Return calc_full($map, $award, $log,$make_forecast)
	Else
		Return 0
	EndIf
EndFunc

Func show_swap(ByRef $map, $r, $c, ByRef $matrix)
	Local $nr = $r + $matrix[0]
	Local $nc = $c + $matrix[1]
	$map[$r][$c] = True
	$map[$nr][$nc] = True
EndFunc

Func apply_spell(ByRef $map, ByRef $award, $r, $c, ByRef $matrix, ByRef $log, $make_forecast = True)
	;If $log Then $log &= "apply_spell(" & $r & ", " & $c & ")" & @CRLF
	Local $affect = 0
	For $i = 0 To UBound($matrix,1) - 1
		Local $nr = $r + $matrix[$i][0]
		Local $nc = $c + $matrix[$i][1]
		If $nr >= 0 And $nr < $row_length And $nc >= 0 And $nc < $col_length Then
			Local $v = $map[$nr][$nc]
			If $v = 0 Then ContinueLoop
			$map[$nr][$nc] = 0
			For $a = 0 To $l_award
				$award[$a] += $field[$v][$a+1]
			Next
			$award[$l_award + 2] += 1
		EndIf
	Next
	;If $log Then $log &= "spell 0" & @CRLF & award_to_str($award) & @CRLF & map_to_str($map) & @CRLF
	trim_map($map, $award, False)
	$award[$l_award + 3] += 1
	forecast_count_drop($map,$award,$log)
	Return calc_full($map, $award, $log,$make_forecast) + 1
EndFunc

Func show_spell(ByRef $map, $r, $c, ByRef $matrix)
	For $i = 0 To UBound($matrix,1) - 1
		Local $nr = $r + $matrix[$i][0]
		Local $nc = $c + $matrix[$i][1]
		If $nr >= 0 And $nr < $row_length And $nc >= 0 And $nc < $col_length Then
			$map[$nr][$nc] = True
		EndIf
	Next
EndFunc

Func find_variant(ByRef $imap, ByRef $log,$fl = False)
	Local $variant[$row_length * $col_length * UBound($move,1)]
	Local $variant_cnt = 0
	For $m = 0 To UBound($move,1) - 1
		Local $group = $move[$m][1]
		Local $v[$row_length * $col_length * UBound($group,1)]
		Local $v_cnt = 0
		For $g = 0 To UBound($group,1) - 1
			For $r = 0 To $row_length - 1
				For $c = 0 To $col_length - 1
					Local $map = $imap
					Local $award = create_award()
					Local $step
					If $fl Then
						$step = call_apply($group[$g][0],$map,$award,$r,$c,$group[$g][2],$log,True)
					Else
						$step = call_apply($group[$g][0],$map,$award,$r,$c,$group[$g][2],False,True)
					EndIf
					If $step > 0 Then
						If $log Then $log &= "call " & $group[$g][0] & " m=" & $m & " g=" & $g & " r=" & $r & " c=" & $c & " ["
						If $log Then $log &= $v_cnt & "] " & award_to_str($award) & @CRLF
						Local $var[6] = [$m,$g,$r,$c,$award,$map]
						$v[$v_cnt] = $var
						$v_cnt += 1
					EndIf
				Next
			Next
		Next

		If $log Then $log &= "------" & @CRLF & "m=" & $m & " cnt=" & $v_cnt & @CRLF
		Local $add

		If $move[$m][2] Then
			$add = find_best_variant($variant,$variant_cnt,$v,$v_cnt,False,$log)
		Else
			$add = 0
			For $vi = 0 To $v_cnt - 1
				$variant[$variant_cnt + $vi] = $v[$vi]
				$add += 1
			Next
		EndIf

		If $log Then
			For $vi = $variant_cnt To $variant_cnt + $add - 1
				Local $var = $variant[$vi]
				Local $award = $var[4]
				$log &= award_to_str($award) & @CRLF
			Next
			$log &= "+++++++ best=" & $add & @CRLF
		EndIf

		$variant_cnt += $add
	Next
	If $variant_cnt > 0 Then
		Local $result[$variant_cnt]
		For $v = 0 To $variant_cnt - 1
			Local $var = $variant[$v]
			forecast_calculate($var[5],$var[4],$log)
			$var[5] = 0
			$result[$v] = $var
		Next
		Return $result
	Else
		Return False
	EndIf
EndFunc

Func find_variant_light(ByRef $imap)
	Local $variant[$row_length * $col_length * UBound($move,1)]
	Local $variant_cnt = 0
	;For $m = 0 To UBound($move,1) - 1
	For $m = 0 To 0
		Local $group = $move[$m][1]
		Local $v[$row_length * $col_length * UBound($group,1)]
		Local $v_cnt = 0
		For $g = 0 To UBound($group,1) - 1
			For $r = 0 To $row_length - 1
				For $c = 0 To $col_length - 1
					Local $map = $imap
					Local $award = create_award()
					Local $step
					$step = call_apply($group[$g][0],$map,$award,$r,$c,$group[$g][2],False,False)
					If $step > 0 Then
						Local $var[5] = [$m,$g,$r,$c,$award]
						$v[$v_cnt] = $var
						$v_cnt += 1
					EndIf
				Next
			Next
		Next
		$variant_cnt += find_best_variant($variant,$variant_cnt,$v,$v_cnt,True,False)
	Next
	If $variant_cnt > 0 Then
		Local $result[$variant_cnt]
		For $v = 0 To $variant_cnt - 1
			$result[$v] = $variant[$v]
		Next
		Return $result
	Else
		Return False
	EndIf
EndFunc
